package com.example.miniodemo.service.impl;

import com.example.miniodemo.common.exception.BusinessException;
import com.example.miniodemo.common.result.ResultEnum;
import com.example.miniodemo.common.service.FileApi;
import com.example.miniodemo.common.util.AssertUtils;
import com.example.miniodemo.common.util.PubUtils;
import io.minio.DownloadObjectArgs;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.http.Method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件上传 业务逻辑层 具体实现
 *
 * @author Lv
 * @date 2022/11/10
 */
@Service
public class FileApiImpl implements FileApi {
    @Autowired
    private MinioClient minioClient;

    /**
     * minio 文件桶
     */
    @Value("${minio.bucket}")
    private String bucket;

    /**
     * 上传单个文件
     *
     * @param multipartFile 文件对象
     * @return
     */
    @Override
    public String uploadFile(MultipartFile multipartFile) {
        // 参数校验
        if (PubUtils.isNull(multipartFile) || PubUtils.isEmpty(multipartFile.getOriginalFilename())) {
            return null;
        }

        try {
            // 构造文件上传对象
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(bucket)
                    .object(multipartFile.getOriginalFilename())
                    .stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
                    .contentType(multipartFile.getContentType())
                    .build();
            // 上传文件
            minioClient.putObject(putObjectArgs);
        } catch (Exception e) {
            BusinessException.exception(ResultEnum.UPLOAD_ERROR);
        }

        // 返回文件路径
        return getUrl(multipartFile.getOriginalFilename());
    }

    /**
     * 获取文件url路径
     *
     * @param fileName 文件名称
     * @return
     */
    private String getUrl(String fileName) {
        String url = null;
        try {
            url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(bucket)
                    .object(fileName)
                    .build());
        } catch (Exception e) {
            BusinessException.exception(ResultEnum.PARAM_INVALID);
        }
        AssertUtils.notEmpty(url, ResultEnum.URL_GET_ERROR);
        return url;
    }

    /**
     * 文件默认下载路径
     */
    @Value("${minio.filePath}")
    private String filePath;

    /**
     * 文件下载
     *
     * @param fileName         文件名称
     * @param fileDownloadPath 文件下载路径
     */
    @Override
    public void download(String fileName, String fileDownloadPath) {
        // 当前端传递的下载路径为空则采用默认下载路径
        if (PubUtils.isEmpty(fileDownloadPath)) {
            fileDownloadPath = filePath;
        }

        try {
            DownloadObjectArgs downloadObjectArgs = DownloadObjectArgs.builder()
                    .bucket(bucket)
                    .object(fileName)
                    .filename(fileDownloadPath + fileName)
                    .build();
            minioClient.downloadObject(downloadObjectArgs);
        } catch (Exception e) {
            BusinessException.exception(ResultEnum.PARAM_INVALID);
        }
    }
}